package com.example.mybank.tool;

import com.example.mybank.entity.Product;
import com.example.mybank.mapper.ProductMapper;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Date;
import java.util.concurrent.TimeUnit;

@Component
public class RedisTool {
    public static final String Pre_Product ="product";
    public static final String Lock_Pre_Product ="lock."+Pre_Product;
    public static final String Lock_Pre_Account ="account";
    public static final String Pre_UsersToken ="token";

//    @Resource
    static RedisTemplate<String,String> redisTemplate;

//    static StringRedisTemplate redisTemplate;

    static ProductMapper productMapper;

    static RedissonClient redissonClient;

    @Autowired
    public void setProductMapper(ProductMapper productMapper){
        RedisTool.productMapper=productMapper;
    }

    @Autowired
    public RedisTool(RedisTemplate redisTemplate,RedissonClient redissonClient) {
        RedisTool.redisTemplate=redisTemplate;
        RedisTool.redissonClient = redissonClient;
    }



    public static RLock product_lock_get(Long id){
        String Key_product = Lock_Pre_Product+"."+id;
        RLock lock = redissonClient.getLock(Key_product);
        return lock;
    }

    public static boolean product_load(Product product){
        Long productID = product.getId();
        RLock lock = product_lock_get(productID);
        try{
            boolean res = lock.tryLock(10, TimeUnit.SECONDS);
            System.out.println("获得锁："+productID);
            System.out.println(res);
            System.out.println(product_hasLoad(productID));
            if(res && !product_hasLoad(productID)){
                product_set(product);
                return true;
            }else{
                return false;
            }
        }catch (Exception e) {

        }finally {
            lock.unlock();
            System.out.println("释放锁："+productID);
        }
        return true;
    }

    // 获得product_key
    public static String product_key_get(Long productID){
        String keyProduct = Pre_Product+"."+productID;
        return keyProduct;
    }
    public static boolean product_set(Product product){
        if( !product.isInTime()){
            return false;
        }

        Long productID = product.getId();
        Long count = product.getCount();


        Date time_end = product.getTime_end();
        Date now = new Date();
        long secondmills = time_end.getTime() - now.getTime() + 10 * 60 *1000; // +10分钟
        System.out.println("product_set: "+product_key_get(productID)+" -> "+secondmills);
        redisTemplate.opsForValue().set(product_key_get(productID),""+count,Duration.ofSeconds(secondmills));
        return true;
    }
    // 获得product是否加载
    public static boolean product_hasLoad(Long productID){
        return redisTemplate.hasKey(product_key_get(productID));
    }
    // 获得product数量自减
    public static long product_decHashValue(Long productID){
        return redisTemplate.opsForValue().decrement(product_key_get(productID),1);
    }
    // 获得product数量自增
    public static long product_incHashValue(Long productID){
        return redisTemplate.opsForValue().increment(product_key_get(productID),1);
    }


    // 获得 token_key
    public static String usersToken_key_get(Long userID){
        String keyUsersToken = Pre_UsersToken+"."+userID;
        return keyUsersToken;
    }
    // put token
    public static long usersToken_set(Long usersID,boolean is_pass){
        long value = is_pass?System.currentTimeMillis():0;
        redisTemplate.opsForValue().set(usersToken_key_get(usersID),""+value, Duration.ofMinutes(10));
        return value;
    }
    // get token
    public static Long usersToken_get(Long userID){
        String token_string = redisTemplate.opsForValue().get(usersToken_key_get(userID));
        Long token = token_string==null?null:Long.valueOf(token_string);// ""+
        return token;
    }
    // delete token
    public static void userToken_delete(Long userID){
        redisTemplate.delete(usersToken_key_get(userID));
    }






    public static RLock account_lock_get(Long id){
        String Key_Account = Lock_Pre_Account+"."+id;
        RLock lock = redissonClient.getLock(Key_Account);
        return lock;
    }

}
